package com.alibaba.algo.domain.user;

import com.alibaba.algo.cooperation.feign.vo.req.*;
import com.alibaba.algo.cooperation.feign.vo.res.CheckRoleInfoResponseVO;
import com.alibaba.algo.cooperation.feign.vo.res.RoleBaseInfoResponseVO;
import com.alibaba.algo.cooperation.feign.vo.res.UserInfoResVO;
import com.alibaba.algo.cooperation.feign.vo.res.UserRoleInfoResVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SelectRoleListRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SelectRoleListResponseVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SysOrgInfoVO;
import com.alibaba.algo.core.base.*;
import com.alibaba.algo.dao.user.SysOrgRoleMapper;
import com.alibaba.algo.dao.user.SysRoleMapper;
import com.alibaba.algo.dtos.user.SysRoleUserDTO;
import com.alibaba.algo.dtos.user.SysUserDTO;
import com.alibaba.algo.entity.user.SysRole;
import com.alibaba.algo.enums.SysRoleTypeEnum;
import com.alibaba.algo.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类SysRole.java的实现描述：角色Domain
 *
 * @author nieganggang 2021-03-12 16:08:17
 */
@Component
public class SysRoleDomain extends BaseDomain<SysRole> {

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private SysOrgRoleMapper sysOrgRoleMapper;

    /**
     * 分页查询角色列表
     *
     * @param vo 入参
     * @return 角色列表
     */
    public PagerEntity<SelectRoleListResponseVO> selectPage(SelectRoleListRequestVO vo) {
        LinkedHashMap<String, Object> sortMap = vo.getSortMap();
        SysRole sysRole = copyToBean(vo);
        Integer total = sysRoleMapper.countByPage(sysRole);
        Pager pager = Pager.newInstance(total.longValue(), vo.getPageIndex(), vo.getPageSize());
        List<SelectRoleListResponseVO> result = sysRoleMapper.selectPage(sysRole, pager.getStart(), pager.getEnd(), CoreTools.getSortStr(sortMap));
        // 将string转为list
        result.forEach(selectRoleListResponseVO -> {
            //查询组织角色关联的组织
            if (SysRoleTypeEnum.ORG_ROLE.getType().equals(selectRoleListResponseVO.getRoleType())) {
                List<SysOrgInfoVO> roleList = sysOrgRoleMapper.selectOrgListByRoleId(selectRoleListResponseVO.getId());
                selectRoleListResponseVO.setOrgList(roleList);
            }
        });
        return new PagerEntity<>(total, pager.getTotalPages(), pager.getPageSize(), pager.getPageIndex(), result);
    }

    public PagerEntity<SelectRoleListResponseVO> permissionSelect(SelectRoleListRequestVO vo) {
        LinkedHashMap<String, Object> sortMap = vo.getSortMap();
        SysRole sysRole = copyToBean(vo);
        Integer total = sysRoleMapper.permissionSelectCount(sysRole);
        Pager pager = Pager.newInstance(total.longValue(), vo.getPageIndex(), vo.getPageSize());
        List<SelectRoleListResponseVO> result = sysRoleMapper.permissionSelect(sysRole, pager.getStart(), pager.getEnd(), CoreTools.getSortStr(sortMap));
        return new PagerEntity<>(total, pager.getTotalPages(), pager.getPageSize(), pager.getPageIndex(), result);
    }

    private SysRole copyToBean(SelectRoleListRequestVO vo) {
        SysRole sysRole = new SysRole();
        sysRole.setSearchKey(vo.getSearchKey());
        if (StringUtil.isDigit(vo.getSearchKey())) {
            sysRole.setId(Long.valueOf(vo.getSearchKey()));
        }
        sysRole.setAppCode(vo.getAppCode());
        sysRole.setRoleCode(vo.getRoleCode());
        sysRole.setRoleName(vo.getRoleName());
        sysRole.setRoleType(vo.getRoleType());
        sysRole.setOrgId(vo.getOrgId());
        sysRole.setOrgCode(vo.getOrgCode());
        sysRole.setRoleDesc(vo.getRoleDesc());
        return sysRole;
    }


    /**
     * 分页查询角色列表
     *
     * @param vo 入参
     * @return 角色列表
     */
    public PagerEntity<SelectRoleListResponseVO> selectOrgRolePage(SelectRoleListRequestVO vo) {
        LinkedHashMap<String, Object> sortMap = vo.getSortMap();
        SysRole sysRole = copyToBean(vo);
        Integer total = sysRoleMapper.countOrgRoleByPage(sysRole);
        Pager pager = Pager.newInstance(total.longValue(), vo.getPageIndex(), vo.getPageSize());
        List<SelectRoleListResponseVO> result = sysRoleMapper.selectOrgRolePage(sysRole, pager.getStart(), pager.getEnd(), CoreTools.getSortStr(sortMap));
        // 将string转为list
        result.forEach(selectRoleListResponseVO -> {
            //查询组织角色关联的组织
            if (SysRoleTypeEnum.ORG_ROLE.getType().equals(selectRoleListResponseVO.getRoleType())) {
                List<SysOrgInfoVO> orgList = sysOrgRoleMapper.selectOrgListByRoleId(selectRoleListResponseVO.getId());
                selectRoleListResponseVO.setOrgList(orgList);
                String orgNames = orgList.stream().map(SysOrgInfoVO::getOrgName).collect(Collectors.joining(","));
                selectRoleListResponseVO.setOrgNames(orgNames);
            }
        });
        return new PagerEntity<>(total, pager.getTotalPages(), pager.getPageSize(), pager.getPageIndex(), result);
    }

    /**
     * 分页查询角色列表（支持查询全量或有效数据）
     *
     * @param vo 入参
     * @return 角色列表
     */
    public PagerEntity<SelectRoleListResponseVO> selectPageWithIsDeleted(SelectRoleListRequestVO vo) {
        LinkedHashMap<String, Object> sortMap = vo.getSortMap();
        SysRole sysRole = copyToBean(vo);
        if (StringUtil.isNotEmpty(vo.getIsDeleted())) {
            sysRole.setIsDeleted(vo.getIsDeleted());
        }
        Integer total = sysRoleMapper.countByPageWithIsDeleted(sysRole);
        Pager pager = Pager.newInstance(total.longValue(), vo.getPageIndex(), vo.getPageSize());
        List<SelectRoleListResponseVO> result = sysRoleMapper.selectPageWithIsDeleted(sysRole, pager.getStart(), pager.getEnd(), CoreTools.getSortStr(sortMap));
        // 将string转为list
        result.forEach(selectRoleListResponseVO -> {
            //查询组织角色关联的组织
            if (SysRoleTypeEnum.ORG_ROLE.getType().equals(selectRoleListResponseVO.getRoleType())) {
                List<SysOrgInfoVO> roleList = sysOrgRoleMapper.selectOrgListWithIsDeletedByRoleId(selectRoleListResponseVO.getId(), selectRoleListResponseVO.getIsDeleted());
                selectRoleListResponseVO.setOrgList(roleList);
            }
        });
        return new PagerEntity<>(total, pager.getTotalPages(), pager.getPageSize(), pager.getPageIndex(), result);
    }

    /**
     * 通过用户列表查询用户信息
     *
     * @param roleIdList 用户列表
     * @return 员工集合
     */
    public Map<Long, SysRole> qryRoleMapByIdList(List<Long> roleIdList) {
        if (CollectionUtils.isEmpty(roleIdList)) {
            return Collections.emptyMap();
        }
        SysRole sysRole = new SysRole();
        sysRole.setRoleIdList(roleIdList);
        List<SysRole> sysRoleList = sysRoleMapper.listByPara(sysRole, null);
        return sysRoleList.stream().collect(Collectors.toMap(BaseEntity::getId, k -> k, (v1, v2) -> v2));
    }

    /**
     * 通过用户列表查询用户信息
     *
     * @param roleIdList 用户列表
     * @return 员工集合
     */
    public Map<Long, SysRole> qryRoleMapWithIsDeletedByIdList(List<Long> roleIdList) {
        if (CollectionUtils.isEmpty(roleIdList)) {
            return Collections.emptyMap();
        }
        SysRole sysRole = new SysRole();
        sysRole.setRoleIdList(roleIdList);
        List<SysRole> sysRoleList = sysRoleMapper.listByParaWithIsDeleted(sysRole, null);
        return sysRoleList.stream().collect(Collectors.toMap(BaseEntity::getId, k -> k, (v1, v2) -> v2));
    }

    /**
     * 支持各种条件查询角色
     *
     * @param param
     * @param sort
     * @return
     */
    public List<SysRole> getRoles(SysRole param, String sort) {
        return sysRoleMapper.listByPara(param, sort);
    }

    /**
     * 根据租户条件和组织条件查询用户
     *
     * @param vo
     * @return
     */
    public List<SysUserDTO> getUsersByApp(SelectOrgUserReqVO vo) {
        return sysRoleMapper.selectUserByApp(vo);
    }

    /**
     * 根据租户条件和组织条件查询用户，默认全量用户
     *
     * @param vo
     * @return
     */
    public List<SysUserDTO> getUsersByAppDefaultAll(SelectOrgUserReqVO vo) {
        return sysRoleMapper.selectUserByAppDefaultAll(vo);
    }

    /**
     * 根据租户条件和组织条件查询用户
     *
     * @param vo
     * @return
     */
    public List<SysUserDTO> getUsersByOrg(SelectOrgUserReqVO vo) {
        return sysRoleMapper.selectUsersByOrg(vo);
    }

    /**
     * 根据租户条件和组织条件查询用户，默认全量用户
     *
     * @param vo
     * @return
     */
    public List<SysUserDTO> getUsersByOrgDefaultAll(SelectOrgUserReqVO vo) {
        if (vo.getPageIndex() != null && vo.getPageSize() != null) {
            return sysRoleMapper.selectUsersByOrgDefaultAll(vo,
                    (vo.getPageIndex() - 1) * vo.getPageSize(), vo.getPageSize());
        } else {
            return sysRoleMapper.selectUsersByOrgDefaultAll(vo, -1, -1);
        }
    }

    public SysRole selectByRoleCode(String roleCode) {
        SysRole sysRole = new SysRole();
        sysRole.setRoleCode(roleCode);
        List<SysRole> list = listByPara(sysRole, null);
        if (list != null && !list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    public SysRole selectByRoleCodeWithIsDeleted(String roleCode) {
        SysRole sysRole = new SysRole();
        sysRole.setRoleCode(roleCode);
        List<SysRole> list = sysRoleMapper.listByParaWithIsDeleted(sysRole, null);
        if (list != null && !list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    public List<UserInfoResVO> getUsersByRole(GetRoleUserReqVO vo) {
        return sysRoleMapper.selectUsersByRole(vo);
    }

    public List<UserInfoResVO> getUsersWithIsDeletedByRole(GetRoleUserReqVO vo) {
        return sysRoleMapper.selectUsersWithIsDeletedByRole(vo);
    }

    public List<SysRoleUserDTO> getUsersByRoles(GetRoleUserReqVO vo) {
        return sysRoleMapper.selectUsersByRoles(vo);
    }

    public void deleteById(Long id) {
        sysRoleMapper.deleteById(id);
    }

    public void updateByIdWithIsDeleted(SysRole sysRole) {
        sysRoleMapper.updateByIdWithIsDeleted(sysRole);
    }

    public PagerEntity<UserRoleInfoResVO> selectUserPageByRoleCondition(SelectUserListByRoleReqVO vo) {
        Integer total = sysRoleMapper.countUserPageByRoleCondition(vo);
        Pager pager = Pager.newInstance(total.longValue(), vo.getPageIndex(), vo.getPageSize());
        List<UserRoleInfoResVO> result = sysRoleMapper.selectUserPageByRoleCondition(vo, pager.getStart(), pager.getEnd(), "userAccount");
        return new PagerEntity<UserRoleInfoResVO>(total, pager.getTotalPages(), pager.getPageSize(), pager.getPageIndex(), result);
    }

    /**
     * 通过角色Id或Code查询角色基本详情
     *
     * @param paramVO
     * @return
     */
    public RoleBaseInfoResponseVO getRoleBaseInfoByIdOrCode(GetRoleBaseInfoReqVO paramVO) {
        return sysRoleMapper.getRoleBaseInfoByIdOrCode(paramVO);
    }

    /**
     * 根据角色Code员工工号租户Code判断是否是该角色
     *
     * @param paramVO
     * @return
     */
    public List<CheckRoleInfoResponseVO> checkRoleByCodeAndEmployee(RoleEmployeeReqVO paramVO) {
        List<CheckRoleInfoResponseVO> dbRes = sysRoleMapper.checkRoleByCodeAndEmployee(paramVO);
        List<CheckRoleInfoResponseVO> result = new ArrayList<>();
        paramVO.getRoleCodeList().stream().forEach(
                item -> {
                    CheckRoleInfoResponseVO element = new CheckRoleInfoResponseVO();
                    element.setEmployeeCode(paramVO.getEmployeeCode());
                    element.setRoleCode(item);
                    if (ObjectUtils.isEmpty(dbRes)) {
                        element.setExist(YesOrNo.N.name());
                    } else {
                        List<String> roleCodeFromDBList = dbRes.stream().map(CheckRoleInfoResponseVO::getRoleCode).collect(Collectors.toList());
                        if (roleCodeFromDBList.contains(item)) {
                            element.setExist(YesOrNo.Y.name());
                        } else {
                            element.setExist(YesOrNo.N.name());
                        }
                    }
                    result.add(element);
                }
        );
        return result;
    }
}
